using UnityEngine;

public class BallShooter : MonoBehaviour
{
	private FlightInitialConditionsSearch search = new FlightInitialConditionsSearch();

	public PlayerControl player;

	public PhysicsBall ball;

	[Range(0.02f, 4f)]
	public float heightAboveNet = 0.2f;

	public FloatRange heightAboveNetRange = default(FloatRange);

	[Range(0f, 1f)]
	public float strength = 0.2f;

	public FloatRange strengthRange = default(FloatRange);

	[Range(-150f, 150f)]
	public float spin;

	public FloatRange spinRange = default(FloatRange);

	[Range(0.02f, 1f)]
	public float timeScale = 1f;

	[Range(0.5f, 5f)]
	public float durationTillShot = 2f;

	[Range(0f, 1f)]
	public float xRange = 0.5f;

	protected MagnusForceAndAirResistanceSquaredBallFlight symFlight = new MagnusForceAndAirResistanceSquaredBallFlight();

	protected float timeTillShot;

	private void Awake()
	{
		Time.timeScale = timeScale;
	}

	private void SetupSearch(Vector3 forwardDirection)
	{
		search.forwardDirection = forwardDirection.normalized;
		search.velocityMagnitudeBoundaries.max = 20f;
		search.heightBoundaries.max = 10f;
		search.symFlight = symFlight;
		search.symDeltaTime = 0.1f;
		search.incomingParams.position = base.transform.position;
	}

	public void ShootBall()
	{
		float num = 0f - Mathf.Sign(base.transform.position.z);
		Vector3 position = base.transform.position;
		Vector3 normalized = (new Vector3(Random.Range(-1f, 1f) * Table.halfwidth * xRange, 0f, 0.5f * num * Table.halfLength) - position).OnGround().normalized;
		SetupSearch(normalized);
		float angle = FlightInitialConditionsSearch.GetAngle(heightAboveNetRange.Random(), 0.02f, position);
		float angularVelocityMagnitude = spinRange.Random();
		FlightInitialConditionsSearch.MaxResult maxResult = search.FindMaxAcceptableVelocity(angle, angularVelocityMagnitude, FlightInitialConditionsSearch.OptimumSearchType.SearchMin);
		FlightInitialConditionsSearch.MaxResult maxResult2 = search.FindMaxAcceptableVelocity(angle, angularVelocityMagnitude, FlightInitialConditionsSearch.OptimumSearchType.SearchMax);
		float velocityMagnitude = Mathf.Lerp(maxResult.magnitude, maxResult2.magnitude, strengthRange.Random());
		FlightParams initialConditions = search.GetInitialConditions(velocityMagnitude, angle, angularVelocityMagnitude);
		FlightSimulator instance = Singleton<FlightSimulator>.instance;
		FlightSimulator.SequenceSimulationParams sim = FlightSimulator.SequenceSimulationParams.DefaultRecordFlightParams(initialConditions, symFlight);
		instance.FillFlightSequence(ball.flightSequence, sim);
		ball.flightSequence.Reset();
		if (player != null)
		{
			player.OnShotBall();
		}
	}

	private void Update()
	{
		if (timeTillShot <= 0f)
		{
			ShootBall();
			timeTillShot = durationTillShot;
		}
		timeTillShot -= Time.deltaTime;
	}

	public void OnBallReturned()
	{
		Debug.Log("Ball returned");
		HitAnimationInfo orCreateHitAnimationByEnum = ScriptableObjectSingleton<KineticAnimationInfoDB>.instance.GetOrCreateHitAnimationByEnum(HitAnimationsStateEnum.BackhandBackspin1);
		KineticPlan.HitPoint hitPoint = KineticPlan.FindHitPointMinimizeZ(ball, base.transform.position.z, 0.05f, orCreateHitAnimationByEnum, base.transform.position);
		if (hitPoint.foundHitPosition)
		{
			base.transform.position = hitPoint.maxPosition;
			timeTillShot = hitPoint.maxTime + hitPoint.stage.startTime;
		}
		else
		{
			Debug.Log("Hit position not found");
		}
	}
}
